import { onBeforeUnmount, ref, shallowRef, StyleValue } from 'vue'
import { uiScreen } from '@/config'
import { FlexibleFactory } from '@lhy-assist/utils'

export interface FlexibleMediaData<V = unknown> {
  // 样式
  style?: StyleValue
  // css类名
  class?: string | string[] | Record<string, any>
  // 任意值
  value?: V
}

export interface FlexibleResponse {
  // <768
  xs: boolean
  // >=768
  sm: boolean
  // >=992
  md: boolean
  // >=1200
  lg: boolean
  // >=1920
  xl: boolean
}

export interface FlexibleResponseData<V = unknown> {
  xs?: FlexibleMediaData<V>
  sm?: FlexibleMediaData<V>
  md?: FlexibleMediaData<V>
  lg?: FlexibleMediaData<V>
  xl?: FlexibleMediaData<V>
  default?: FlexibleMediaData<V>
}

/**
 * 响应服务
 *
 * @param options
 * @returns
 */
export function useFlexible<R extends Record<string, boolean>>(options?: {
  onFlexibleResponseChanged?: (response: FlexibleResponse) => R | void
}) {
  const docEl = document.documentElement
  const flexibleRatio = shallowRef(1)
  const flexibleResponse = ref<FlexibleResponse>({
    xs: false,
    sm: false,
    md: false,
    lg: false,
    xl: false,
  })
  const userFlexibleResponse = ref<R>()

  function updateFlexibleRatio() {
    flexibleRatio.value = docEl.clientWidth / uiScreen.width
  }

  function updateFlexibleResponse() {
    const width = docEl.clientWidth
    const newResponse: FlexibleResponse = {
      xs: false,
      sm: false,
      md: false,
      lg: false,
      xl: false,
    }
    if (width < 768) {
      newResponse.xs = true
    } else {
      newResponse.sm = true

      if (width >= 992) {
        newResponse.md = true
      }
      if (width >= 1200) {
        newResponse.lg = true
      }
      if (width >= 1920) {
        newResponse.xl = true
      }
    }

    flexibleResponse.value = newResponse
    userFlexibleResponse.value = options?.onFlexibleResponseChanged?.(newResponse) || undefined
  }

  FlexibleFactory.initEvents().addHandlers(updateFlexibleRatio, updateFlexibleResponse).update()

  onBeforeUnmount(() => {
    FlexibleFactory.removeHandlers(updateFlexibleRatio, updateFlexibleResponse).removeEvents()
  })

  return {
    flexibleRatio,
    flexibleResponse,
    userFlexibleResponse,
  }
}

/**
 * 响应数据服务
 *
 * @param userData
 * @param options
 * @returns
 */
export function useFlexibleData<V = unknown>(
  userData: FlexibleResponseData<V>,
  options?: { onChange?: (data: FlexibleResponseData<V>[keyof FlexibleResponseData<V>]) => void }
) {
  const responseData = shallowRef<FlexibleResponseData<V>[keyof FlexibleResponseData<V>]>()
  const { flexibleRatio, flexibleResponse } = useFlexible({
    onFlexibleResponseChanged(response) {
      let newData: FlexibleResponseData<V>[keyof FlexibleResponseData<V>]
      if (response.xs) {
        newData = userData.xs
      } else if (response.sm) {
        newData = userData.sm
      } else if (response.md) {
        newData = userData.md
      } else if (response.lg) {
        newData = userData.lg
      } else if (response.xl) {
        newData = userData.xl
      }

      if (newData == null) {
        newData = userData.default
      }

      responseData.value = newData
      options?.onChange?.(newData)
    },
  })

  return {
    responseData,
    flexibleRatio,
    flexibleResponse,
  }
}

/**
 * 换算成rem
 *
 * @param px
 * @returns
 */
export function getFlexibleSize(px: string) {
  const value = Number(String(px).replace(/px$/i, ''))
  return (value * 10) / uiScreen.width + 'rem'
}
